<!--这个渲染程序将生成数据集作用域dataScope-->
<template>
  <q-card class="fit editor-area">
    <div class="fit no-wrap column">
      <div v-if="!hideHeader" class="panel-header text-subtitle2 text-blue-grey-9 row nowrap" style="padding: 5px 15px;">
        <div>画布</div>
        <div class="size-inner row nowrap items-center q-px-md">
          <div>宽：</div>
          <input v-model="preference.width" type="number" style="width: 60px;">
          <div>px</div>
          <div class="q-pl-md">高：</div>
          <input v-model="preference.height" type="number" style="width: 60px;">
          <div>px</div>
        </div>
        <q-btn icon="refresh" @click="sk.refresh()" dense flat></q-btn>
      </div>
      <div @mousedown="fix ? () => {} : moveRelate($event, `.pix-back`)"
           class="overflow-auto column justify-around items-center no-wrap center-center panel-body"
           style="background-color: #f4f4f4;">
        <div class="pix-back page-canvas" :style="sizeStyle">
          <div class="fit flex row justify-center items-center">
            <EditorSkeleton ref="sk" v-if="show" :vnode="vnode" v-bind="allScope"></EditorSkeleton>
          </div>
        </div>
      </div>
    </div>
  </q-card>
</template>

<script setup>
import {computed, onBeforeMount, onMounted, provide, ref, toRefs, watch} from 'vue';
import {deepMerge, moveRelate, treeDel, treeFind, treeFindParent, treeMap} from 'dlsjs';
import {clone} from 'ramda';
import EditorSkeleton from './EditorSkeleton.vue';
import {v4 as uuidv4} from 'uuid'

const emits = defineEmits(['event', 'changeSelectNode'])
const props = defineProps({
  vnode: {
    type: Object,
    default: () => ({})
  },
  dataScope: {
    type: Object
  },
  readonly: {
    type: Boolean
  },
  expose: {
    type: Object,
    default: () => ({})
  },
  defaultSize: {
    type: Object,
    default: () => ({
      width: 1440,
      height: 760,
      unit: 'px'
    })
  }, // 默认画布尺寸
  hideHeader: Boolean, // 隐藏头部
  fix: Boolean, // 画布固定，禁止拖拽
  devMode: Boolean, // 开发模式，所有蒙版均可操作
  readonlyMode: Boolean, // 只读模式，所有蒙版不可操作
  permsMode: Boolean // 权限模式，只显示权限蒙版
})

provide('permsMode', props.permsMode)
provide('devMode', props.devMode)
provide('readonlyMode', props.readonlyMode)
const sk = ref()
const preference = ref({
  width: 100,
  height: 100,
  unit: '%'
})
const sizeStyle = computed(() => {
  return {
    width: preference.value.width + preference.value.unit,
    height: preference.value.height + preference.value.unit,
  }
})

/**
 * 初始化四种内部作用域
 * @property dataScope 数据作用域
 * @property funcScope 函数作用域
 * @property refScope 组件作用域 todo 未渲染的组件将不会出现在这里,编辑模式下引用弹窗将会引起不变
 * @property slotScope 插槽作用域 todo 待完善多插槽作用域情况
 */
const allScope = ref({
  dataScope: {},
  funcScope: {emits: emits},
  refScope: {},
  slotScope: {},
})
const {pageOption} = toRefs(props)

/**
 * 初始化外部节点树区域
 * @type {Ref<any>}
 */
onBeforeMount(async () => {
  if (props.dataScope) allScope.value.dataScope = props.dataScope
  if (props.readonly) pageOption.value.vnode['@permLevel'] = 'readonly'
})

/**
 * 覆盖数据域
 * @param obj
 */
function mergeData(obj) {
  deepMerge(allScope.value.dataScope, obj)
}

/**
 * 记录悬浮hover的栈
 * @type {Ref<UnwrapRef<*[]>>}
 */
const mouseOverUidStack = ref([])
provide('mouseOverUidStack', mouseOverUidStack)

/**
 * 删除一个节点
 * @param uuid
 */
function delNode(uuid) {
  treeDel([props.vnode], item => item.uuid === uuid)
}
/**
 * 复制一个节点
 * @param uuid
 */
function copyNode(uuid) {
  let parent = treeFindParent([props.vnode], item => item.uuid === uuid)
  let index = parent.children.findIndex(item => item.uuid === uuid)
  let node = clone(parent.children.find(item => item.uuid === uuid))
  parent.children.splice(index, 0, Object.assign(node, {uuid: uuidv4()}))
}

provide('delNode', delNode)
provide('copyNode', copyNode)

/**
 * 选中父级节点
 * @param uuid
 */
function checkParentNode(uuid) {
  selectVnodeId.value = treeFindParent([props.vnode], item => item.uuid === uuid)?.uuid
}

provide('checkParentNode', checkParentNode)

/**
 * 当前选中节点uuid
 * @type {Ref<UnwrapRef<string>>}
 */
const selectVnodeId = ref('')
provide('selectVnodeId', selectVnodeId)

/**
 * 切换选中节点时读取节点全部信息
 */
watch(selectVnodeId, () => {
  const node = treeFind([props.vnode], item => item.uuid === selectVnodeId.value)
  emits('changeSelectNode', node)
})

onBeforeMount(() => {
  preference.value.width = props.defaultSize.width
  preference.value.height = props.defaultSize.height
  preference.value.unit = props.defaultSize.unit
})

const show = ref(true)
function refresh() {
  show.value = false
  setTimeout(() => show.value = true, 0)
}

function getPermLevel() {
  return treeMap([props.vnode], item => {
    if(item.uuid) {
      return {'@permLevel': item['@permLevel'] || null, uuid: item.uuid}
    }else {
      return null
    }
  })
}

defineExpose({allScope, mergeData, delNode, refresh, getPermLevel})
</script>

<style scoped lang="scss">
.editor-area {
  background-color: transparent;
  :deep(.readonlyEditor:not(.readonlyEditor .readonlyEditor):after) {
    content: '';
    position: absolute;
    display: block;
    width: 100%;
    height: 100%;
    background: #00000022;
    z-index: 1;
    overflow: hidden;
    top: 0;
    left: 0;
  }
  :deep(.hideEditor:not(.hideEditor .hideEditor):after) {
    content: '';
    position: absolute;
    display: block;
    width: 100%;
    height: 100%;
    background: #FFFFFF99;
    z-index: 1;
    overflow: hidden;
    outline: 1px solid #cccccc;
    top: 0;
    left: 0;
  }
}
.pix-back {
  background:#eee;
  background-image:
    linear-gradient(45deg,
    rgba(0,0,0,.09)25%,transparent 0,
    transparent 75%,rgba(0,0,0,.09)0),
    linear-gradient(45deg,
    rgba(0,0,0,.09)25%,transparent 0,
    transparent 75%,rgba(0,0,0,.09)0);
  background-position:0 0,15px 15px;
  background-size: 30px 30px;
}
.page-canvas {
  position: relative;
  z-index: 1;
}
.panel-header {
  height: 32px;
  border-bottom: 1px solid #e5e5e5;
}
.panel-body {
  height: 100%;
}
.size-inner {
  align-self: center;
  input {
    height: 20px;
  }
}
</style>
